#pragma once
#include "Effect.h"
#include "FXParameter.h"
#include "ObjMesh.h"
#include "util.h"
#include <map>

class ShaderParameter;
class Effect;
class Technique;
/**
* Abstraction of the properties for a shader.
* @author Koen Samyn
*/
class ShaderMaterial
{
public:
	/**
	* Creates a new ShaderMaterial object.
	* @param technique a pointer to the technique object to use.
	*/
	ShaderMaterial(Technique* technique);
	/**
	* Deletes the ShaderMaterial object.
	*/
	virtual ~ShaderMaterial(void);
	/**
	* Customizes an effect parameter for this material.
	* @param name the parameter to customize.
	*/
	virtual FXParameter* CustomizeParameterByName(tstring name) = 0;
	/**
	* Add a parameter with the specified name to this shader material.
	* @param name the name of the parameter.
	* @param parameter the shader parameter.
	*/
	void AddParameter(tstring name, FXParameter* parameter);
	/**
	* Finds a ShaderParameter with the specified name.
	* @param name the name of the parameter.
	* @return the ShaderParameter object, NULL if the parameter was not found.
	*/
	FXParameter* GetParameter(tstring name);
	/**
	* Passes all the parameters to the shader.
	* @param device the device to use.
	*/
	//virtual void SetInEffect(Device3D* device)=0;
	/**
	* Passes a single parameter to the shader.
	* @param device the device to use.
	* @param parameter the parameter to set.
	*/
	//virtual void SetInEffect(Device3D* device,ShaderParameter* parameter)=0;
	/**
	* Draw the mesh with this Material.
	* @param device the device to use for the drawing operation.
	* @param mesh the mesh to draw.
	*/
	//virtual void Draw(Device3D* device,Mesh* mesh)=0;
	/**
	* Draws the mesh , but with a specified technique.
	* This is useful for drawing shadow maps.
	* @param device the device to use for this draw operation.
	* @param mesh the mesh to draw.
	* @param technique the technique to use.
	*/
	//virtual void Draw(Device3D* device, Mesh* mesh, tstring technique) = 0;
	/**
	* Activate the shader, this is useful to draw a lot of objects
	* with the same shader. This also activates the first pass.
	*/
	virtual void Activate() =0;
	/**
	* Activates the given technique for the shader. If the technique
	* does not exist, the standard technique will be used.
	*/
	virtual void Activate(tstring technique) = 0;

	/**
	* Activates the next pass in the shader.
	* @return true if there is a next pass, false otherwise.
	*/
	virtual bool NextPass()=0;
	/**
	* If parameters were changed, commit the changes.
	*/
	virtual void CommitChanges()=0;
	
	
	
protected:
	/**
	* The pointer to the technique
	*/
	Technique* m_pTechnique;
	/**
	* The map with the parameters.
	*/
	map<tstring, FXParameter*> m_NameMap;
private:
	// -------------------------
	// Disabling default copy constructor and default assignment operator.
	// If you get a linker error from one of these functions, your class is internally trying to use them. This is
	// an error in your class, these declarations are deliberately made without implementation because they should never be used.
	// -------------------------
	ShaderMaterial(const ShaderMaterial& t);
	ShaderMaterial& operator=(const ShaderMaterial& t);
};
